//
//  main.m
//  RadixTransformation
//
//  Created by lianglibao on 2019/3/16.
//  Copyright © 2019年 lianglibao. All rights reserved.
//

#import <Foundation/Foundation.h>
//将十进制数用16进制输出
void noun(int n) {
    char nu[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};  //16进制数表
    int coun = 8;  //为什么是8?因为16进制数对应二进制为4位,所以二进制可以拆为8个4位一组
    char result[8] = {'0'};  //由coun为8,所以需要定义元素为8的长度来存储
    while(n != 0) {
        int num = n & 15;//00001010
        //                                 1111
        //                                 1010-->10
        // 利用这个值作为索引去数组中查询对应的十六进制的值
        char c = nu[num];
        result[--coun] = c;   // 将取出来得值放到用于存储结果数组中  //result[7]=a
        n = n >> 4;           // 每取完一次就干掉它最低的4位,因为16进制用二进制是4位
    }
    for (int i = coun;i < 8;i++) {
        printf("%c \n",result[i]);
    }
}

// 将十进制数用8进制输出
void eight(int n) {
    char nu[] = {'0','1','2','3','4','5','6','7'};
    int count = 11;
    char result[11] = {'0'};
    while(n != 0){
        int num = n & 7;
        char c = nu[num];
        result[--count] = c;
        n = n >> 3;
	}
    for(int i = count;i < 11;i++){
        printf("%c",result[i]);
    }
    printf("\n");
}

// 将十进制数用2进制输出
void binary(int n) {
    char nu[] = {'0','1'};
    int count = 32;
    char result[32] = {'0'};
    while(n != 0){
        int num = n & 1;
        char c = nu[num];
        result[--count] = c;
        n = n >> 1;
	}
    for(int i = count;i < 32;i++){
        printf("%c",result[i]);
    }
    printf("\n");
}

// 优化的进制算法函数实现

/**
 @param value 需要查表数字
 @param base 与计算隐码 1, 7, 15
 @param offset 偏移隐码 1, 3, 4
 */
void optimize(int value, int base, int offset) {
    // 1.定义一个数组, 用于保存十六进制中所有的取值
    char charValues[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    // 2.定义一个数组, 用于保存查询后的结果
	// 数组长度为32,因为int类型占4个字节-->32位,而一个二进制数占1个字节,为了兼容输出二进制.
    char results[32] = {'0'};
    // 3.定义一个变量, 用于记录当前需要存储到查询结果数组的索引
    int pos = 32;  // sizeof(results)/ sizeof(results[0])
    
    while (value != 0) {
        // 1.取出1位的值
        int res = value & base;// 1 7 15
        // 2.利用取出来得值到表中查询对应的结果
        char c = charValues[res];
        // 3.存储查询的结果
        results[--pos] = c;
        // 4.移除二进制被取过的1位
        value = value >> offset;// 1 3 4
    }
    
    // 4.打印结果
    for (int i = pos; i < 32; i++) {
        printf("%c", results[i]);
    }
    printf("\n");
}

// 16进制输出函数
void printfHex(int num) {
    optimize(num, 15, 4);
}

// 8进制输出函数
void printfOct(int num) {
    optimize(num, 7, 3);
}

// 2进制输出函数
void printfBinary(int num) {
    optimize(num, 1, 1);
}


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        printfOct(10);
        printfHex(10);
        printfBinary(18);
        binary(18);
    }
    return 0;
}
